def viterbi(obs_seq, A, B):
    T = len(obs_seq)  # 获取观测序列的长度
    delta = [[0] * pos_tag_count for _ in range(T)]  # 初始化 delta 矩阵
    prev = [[0] * pos_tag_count for _ in range(T)]  # 初始化 prev 矩阵
    for i in range(pos_tag_count):
        delta[0][i] = A[0][i] * B[i][obs_seq[0]]  # 初始化 delta 的第一行
    for t in range(1, T):
        for i in range(pos_tag_count):
            max_prob = 0  # 初始化最大概率为 0
            max_prev = 0  # 初始化最大概率对应的前一个状态为 0
            for j in range(pos_tag_count):
                prob = delta[t - 1][j] * A[j][i] * B[i][obs_seq[t]]  # 计算当前状态的概率
                if prob > max_prob:  # 如果当前概率大于最大概率
                    max_prob = prob  # 更新最大概率
                    max_prev = j  # 更新最大概率对应的前一个状态
            delta[t][i] = max_prob  # 更新 delta 矩阵
            prev[t][i] = max_prev  # 更新 prev 矩阵
    max_prob = 0  # 初始化最大概率为 0
    max_state = 0  # 初始化最大概率对应的状态为 0
    for i in range(pos_tag_count):
        if delta[T - 1][i] > max_prob:  # 如果当前概率大于最大概率
            max_prob = delta[T - 1][i]  # 更新最大概率
            max_state = i  # 更新最大概率对应的状态
    path = [max_state]  # 初始化路径为最大概率对应的状态
    for t in range(T - 1, 0, -1):
        state = prev[t][path[-1]]  # 获取当前状态的前一个状态
        path.append(state)  # 将前一个状态添加到路径中
    path.reverse()  # 反转路径
 
    return path